/**
 * 舱单mixins
 */
import $ from 'jquery'
import axios from '@/libs/api.request'
import {
    getManifestList,
    queryManifestById,
    unifySaveManifest,
    sendManifestToSingleWindow,
    getDeclareBasicData,
    getManifestBasicData
} from '@/api/manifest.js'
import {
    getManifestErrorForm,
    getManifestRules,
    getConsignmentErrorForm,
    getConsignmentRules
} from './manifast-form-rules'
import commonJs from './common'

/**
 * 根据批次号查询舱单信息
 * @param {String} value 批次号
 * @param {String} manifestType 舱单类型
 * @param {Function} cb 回调方法
 */
async function queryManifestByBatchNo (value, manifestType, cb) {
    const listResponse = await getManifestList({
        cargoBatchNo: value,
        manifestType,
        pageNum: 1,
        pageSize: 1
    })
    if (listResponse.data.responseCode !== '0000') return
    const data = listResponse.data.data.list[0]
    if (!data) return
    cb && cb(data)
}
function getDataListCommFn (options) {
    let cacheData = sessionStorage.getItem(options.sessionKey)
    if (cacheData) {
        return new Promise((resolve, reject) => {
            resolve(JSON.parse(cacheData))
        })
    }
    let data = {
        dataMainType: options.dataMainType,
        pageNum: 1,
        pageSize: 10000
    }
    const fn = options.type === 1 ? getDeclareBasicData : getManifestBasicData // type: 1-报关单基础数据字典接口  2-舱单基础数据字典接口
    return fn(data).then(res => {
        let list = []
        if (res.data.success) {
            list = res.data.data.list
            if (list.length > 0) {
                sessionStorage.setItem(options.sessionKey, JSON.stringify(list))
            }
        }
        return list
    })
}

/**
 * 舱单基础表单的mixins
 * 根据运输批次号查询舱单信息mixins（增加批次号回车方法， 抽离原有assignment方法 ）
 * 修改表单样式， 增加 基本信息表单错误数据 替换 校验规则 customsManifestRules
 */
export const manifestBaseMixins = {
    data () {
        const manifestErrForm = getManifestErrorForm()
        const customsManifestRules = getManifestRules((key, err) => {
            this.manifestErrForm[key] = err
        })
        return {
            // 错误信息
            manifestErrForm,
            customsManifestRules // 校验信息
        }
    },
    mounted () {
        this.getBaseList()
        this.initPage()
    },
    watch: {
        'billsForm.consignmentStatus' (n, o) {
            this.billsEdit = ['', 'P', 'A1', 'A03', 'D0'].indexOf(n) < 0
            this.billsHandleBtnText = this.billsEdit ? '修改' : '保存'
        }
    },
    methods: {
        // 获取数据字典
        getBaseList () {
            // 获取海关信息
            getDataListCommFn({
                sessionKey: 'customsCodeList',
                dataMainType: 'CUSTOMS_CODE',
                type: 1
            }).then(list => { this.customsCodeList = Object.freeze(list) })
            // 获得支付方式
            getDataListCommFn({
                sessionKey: 'mPaymentList',
                dataMainType: 'FREIGHT_PAYMENT_METHOD',
                type: 2
            }).then(list => { this.mPaymentList = Object.freeze(list) })
            // 获得包装类型
            getDataListCommFn({
                sessionKey: 'mPackingTypeList',
                dataMainType: 'PACKING_TYPE',
                type: 2
            }).then(list => { this.mPackingTypeList = Object.freeze(list) })
            // 获得金额类型
            getDataListCommFn({
                sessionKey: 'amountTypeList',
                dataMainType: 'CURRENCY_CODE',
                type: 1
            }).then(list => { this.amountTypeList = Object.freeze(list) })
            // 获得重箱或空箱标识字典
            getDataListCommFn({
                sessionKey: 'mContainerFlagList',
                dataMainType: 'CONTAINER_FLAG',
                type: 2
            }).then(list => { this.mContainerFlagList = Object.freeze(list) })
            // 获得运输条款数据字典
            getDataListCommFn({
                sessionKey: 'mConditionCodeList',
                dataMainType: 'CONDITION_CODE',
                type: 2
            }).then(list => { this.mConditionCodeList = Object.freeze(list) })
            // 获得海关货物通关代码数据字典
            getDataListCommFn({
                sessionKey: 'mCargoClearanceList',
                dataMainType: 'CLEARANCE_CODE',
                type: 2
            }).then(list => { this.mCargoClearanceList = Object.freeze(list) })
            // 获得运输方式代码数据字典
            getDataListCommFn({
                sessionKey: 'mTransportTypeList',
                dataMainType: 'TRANSPORT_TYPE',
                type: 2
            }).then(list => { this.mTransportTypeList = Object.freeze(list) })
            // 获得途径国家数据字典
            getDataListCommFn({
                sessionKey: 'mCountryList',
                dataMainType: 'ROUTING_COUNTRY',
                type: 2
            }).then(list => { this.mCountryList = Object.freeze(list) })
        },
        // 初始化页面数据
        initPage () {
            const manifestId = this.$route.params.manifestId
            if (manifestId) {
                if (this.manifestId !== manifestId) {
                    this.manifestId = manifestId
                    this.disabled = this.$route.path.includes('view') // 判断是否查看页面
                    this.getManifestInfo(manifestId)
                    this.$nextTick(() => {
                        this.clearBillsForm()
                    })
                }
            } else {
                this.disabled = false
                this.billsDataCurrentIndex = ''
                this.parentParams = {}
            }
        },
        // 赋初始值
        assignment (data) {
            this.manifestId = data.manifestId
            for (let i in this.customsManifest) {
                this.customsManifest[i] = data[i]
            }

            this.customsManifest.loadingDate = new Date(
                this.customsManifest.loadingDate
            )
            if (this.customsManifest.manifestType === 'MT1401') {
                this.customsManifest.arrivalDate = this.customsManifest
                    .arrivalDate
                    ? new Date(this.customsManifest.arrivalDate)
                    : ''
            }
            this.consignmentSaveVos = data.consignmentVoList

            if (!this.customsManifest.representativePerson && this.companyObj.representativePerson &&
                 this.companyObj.customsMaster && this.companyObj.clientId && this.companyObj.representativeCode) {
                this.customsManifest.representativePerson = this.companyObj.representativePerson
                this.customsManifest.representativeCode = this.companyObj.representativeCode
                this.customsManifest.customsMaster = this.companyObj.customsMaster
            }
        },
        // 查询舱单信息
        getManifestInfo (manifestId) {
            let url = '/customs/manifest/queryManifestById?manifestId=' + manifestId
            axios.request({
                url: url,
                method: 'get'
            }).then(res => {
                if (res.data.success) {
                    this.assignment(res.data.data) // 赋初始值
                } else {
                    this.$refs.errorModalRef.init(res.data.msg)
                }
            })
        },
        // 查询公司信息 舱单传输人信息等
        getCompanyInfo () {
            axios.request({
                url: '/customs/sys/queryCurrCompany'
            }).then(res => {
                if (res.success) {
                    let data = res.data
                    for (let i in this.companyObj) {
                        this.companyObj[i] = data[i]
                    }
                    if (data.representativePerson && data.customsMaster && data.clientId && data.representativeCode) {
                        this.customsManifest.representativePerson = data.representativePerson
                        this.customsManifest.representativeCode = data.representativeCode
                        this.customsManifest.customsMaster = data.customsMaster
                    }
                }
            })
        },
        // 通过货物运输批次号获得舱单信息
        queryManifest (obj) {
            this.customsManifest.cargoBatchNo = obj.cargoBatchNo
            this.manifestId = obj.manifestId
            let url = '/customs/manifest/queryManifestById?manifestId=' + obj.manifestId
            axios.request({
                url: url,
                method: 'get'
            }).then(res => {
                if (res.data.success) {
                    this.assignment(res.data.data) // 赋初始值
                    $('.transportType').find('.ivu-select-input').focus()
                } else {
                    this.$refs.errorModalRef.init(res.data.msg)
                }
            })
        },
        // 运输批次号回车事件
        handleBatchNoEnter () {
            const { cargoBatchNo, manifestType } = this.customsManifest
            cargoBatchNo && queryManifestByBatchNo(cargoBatchNo, manifestType, this.assignment)
        },
        // 打开批次号查询弹窗
        openCargoBatchNoModal () {
            if (this.disabled) return
            this.$refs.cargoBatchNoModalRef.init(this.customsManifest.manifestType, this.customsManifest.cargoBatchNo, this.$route.params.trainingId)
        },
        // 根据id查询舱单信息
        queryManifestInfo (id) {
            return queryManifestById(id).then(res => {
                if (res.data.success) {
                    this.assignment(res.data.data) // 赋初始值
                } else {
                    this.$Message.error(res.data.msg)
                }
                return res
            }).catch(err => {
                console.log(err)
            })
        },
        sendToSingleWindowHandle (obj) {
            sendManifestToSingleWindow(obj).then(res => {
                if (res.data.success) {
                    if (obj.functionCode === 3) {
                        this.$Message.success('删除成功')
                    }
                    if (obj.functionCode === 5) {
                        this.$Message.success('修改成功')
                    }
                } else {
                    if (obj.functionCode === 3) {
                        this.$refs.declareFailureRef.init(res.data.data, {}, '删除失败') // 删除成功
                    }
                    if (obj.functionCode === 5) {
                        let tempObj = {
                            manifestId: obj.manifestId,
                            consignmentIds: obj.consignmentIds,
                            functionCode: obj.functionCode,
                            changeReasonCode: obj.changeReasonCode
                        }
                        this.$refs.declareFailureRef.init(res.data.data, tempObj, '修改失败') // 修改失败
                    }
                }
            })
        },

        updateHandle (consignmentId) {
            let obj = {
                manifestId: this.manifestId,
                consignmentIds: consignmentId,
                functionCode: 5
            }
            this.$refs.changeReasonModalRef.init(obj)
        },
        // 组装保存的数据
        assemblData () {
            let customsManifest = JSON.parse(JSON.stringify(this.customsManifest))
            customsManifest.arrivalDate = commonJs.formatTimeToUnix(customsManifest.arrivalDate)
            customsManifest.loadingDate = commonJs.formatTimeToUnix(customsManifest.loadingDate)
            customsManifest.practicalTrainingId = this.$route.params.trainingId
            let params = {
                customsManifest: customsManifest,
                consignmentSaveVos: this.consignmentSaveVos
            }
            if (this.manifestId) {
                params.customsManifest.manifestId = this.manifestId
            }
            params.consignmentSaveVos.forEach((item, index) => { // 设置提运单 consignmentIndex
                item.consignmentIndex = index + 1
            })
            return params
        },
        // 保存舱单
        saveManifest () {
            this.$refs['customsManifestRef'].validate((valid) => {
                if (valid) {
                    let params = this.assemblData()
                    unifySaveManifest(params).then(res => {
                        if (res.data.success) {
                            this.manifestId = res.data.data.success
                            this.$Message.success('保存成功！')
                        } else {
                            this.$Message.warning(res.data.msg)
                        }
                    })
                }
            })
        },
        // 设置焦点
        setFocus (e) {
            if (e.keyCode === 13) {
                let target = $(e.target).parents('.ivu-form-item').next()

                if (target.find('.ivu-select-disabled').length > 0) {
                    target = target.next()
                }

                if (target.find('.ivu-select-input').length) {
                    target.find('.ivu-select-input').focus()
                } else if (target.find('.ivu-input').length) {
                    target.find('.ivu-input').focus()
                }
            }
        },
        // 完善舱单传输人信息后
        saveRepresentative (companyForm) {
            for (let i in companyForm) {
                this.companyObj[i] = companyForm[i]
            }
            this.customsManifest.representativePerson = companyForm.representativePerson
            this.customsManifest.representativeCode = companyForm.representativeCode
            this.customsManifest.customsMaster = companyForm.customsMaster
            let list = this.selectedBillsData
            let tempArr = []
            list.forEach(item => {
                tempArr.push(item.consignmentId)
            })
            let obj = {
                manifestId: this.manifestId,
                consignmentIds: tempArr.join(),
                functionCode: 9
            }
            /**
             * 申报提运单步骤：1、保存舱单   2、申报提运单   3、如果有error，弹窗，可取消，不可继续申报
             *                 4、如果有wain，弹窗，可继续申报
             * */

            let params = this.assemblData()
            unifySaveManifest(params).then(res => { // 保存舱单
                if (res.data.success) { // 申报提运单
                    this.manifestId = res.data.data.success
                    this.billsDeclareHandle(obj)
                } else {
                    this.$Message.error(res.data.msg)
                }
            })
        }
    }
}

/**
 * 海关货物通关代码默认选中：公路口岸直通 (抽离 data中的 billsForm， 及 单击表格方法 billsRowClick 统一处理)
 * 修改表单样式， 增加 基本信息表单错误数据 替换 校验规则 customsManifestRules
 */
export const consignmentVoMixins = {
    data () {
        const billsFormRules = getConsignmentRules((key, err) => {
            this.billsErrForm[key] = err
        })
        const billsErrForm = getConsignmentErrorForm()
        return {
            // 提运单表单验证
            billsFormRules,
            // 提运单错误信息
            billsErrForm,
            // 提运单信息表单
            billsForm: {
                consignmentIndex: '',
                billNo: '',
                conditionCode: '',
                freightPaymentMethods: '1', // 默认
                cargoClearanceCode: 'RD01', // 默认公路口岸直通
                countryInfo: '',
                totalPackageQuantity: '',
                packingType: '',
                grossVolumeMeasure: '',
                totalGrossMeasure: '',
                cargoValue: '',
                amountType: '',
                deconsolidator: '',
                transitDestination: '',
                consigneeId: '',
                consigneeName: '',
                consignorId: '',
                consignorName: '',
                notifyId: '',
                dangercontactId: '',
                consignmentStatus: '',
                changeReasonCode: '', // 更改原因
                consignmentCountryList: [], // 途径国家数组
                consignmentCargoVos: [],
                consignmentContainers: [],
                consignmentId: ''
            }
        }
    },
    methods: {
        // 危险品联系人回车事件
        dangercontactIdEnter (e) {
            this.$nextTick(() => {
                this.handlerBillsForm()
            })
        },
        // 保存商品信息
        saveGoodsInfo (obj) {
            let index = obj.index
            this.consignmentSaveVos[index].consignmentCargoVos = obj.list
        },
        // 保存集装箱信息
        saveContainerInfo (obj) {
            let index = obj.index
            this.consignmentSaveVos[index].consignmentContainers = obj.list
        },
        // 提运单表格勾选
        billsSelectChange (selection, row) {
            this.selectedBillsData = selection
        },
        // 设置当前选中的提运单样式
        setCurrentRowClass (row, index) {
            if (index === this.billsDataCurrentIndex) {
                return 'bills-current-row'
            }
        },
        // 提运单新增
        clearBillsForm () {
            const def = {
                consignmentCountryList: [],
                consignmentCargoVos: [],
                consignmentContainers: []
            }
            Object.keys(this.billsForm).forEach(k => {
                this.billsForm[k] = def[k] || ''
            })
            this.billsDataCurrentIndex = ''
            this.parentParams = {}
            this.resetBillsForm()
        },
        // 提运单复制
        copyBillsItem () {
            let list = this.selectedBillsData
            if (list.length === 0) {
                this.$Message.warning('请选择提运单')
                return false
            }
            const keys = Object.keys(this.billsForm)
            const len = this.consignmentSaveVos.length + 1
            list.forEach((item, i) => {
                let data = {}
                keys.forEach(k => {
                    data[k] = item[k]
                })
                data.consignmentStatus = 'P' // 复制状态为 暂存
                data.consignmentId = ''
                data.consignmentIndex = len + i
                this.consignmentSaveVos.push(data)
            })
            this.selectedBillsData = []
        },
        // 提运单查看回执
        showReceipt () {
            let len = this.selectedBillsData.length
            if (len === 1) {
                this.$refs.receiptModalRef.init(this.selectedBillsData[0].consignmentId)
            } else {
                this.$Message.warning(
                    len <= 0 ? '请选择提运单' : '只能查看一条提运单的回执信息'
                )
            }
        },
        // 重置提运单表单
        resetBillsForm () {
            // 清空校验
            this.$refs.billsFormRef.resetFields()
            this.$nextTick(() => {
                Object.keys(this.billsErrForm).forEach(k => {
                    this.billsErrForm[k] = ''
                })
            })
        },
        // 提运单删除
        deleteBillsItem () {
            let list = this.selectedBillsData.slice()
            let consignmentSaveVos = this.consignmentSaveVos
            this.selectedBillsData = []
            if (list.length === 0) {
                this.$Message.warning('请选择提运单')
                return false
            }

            // 查询哪些是需要物理删除的
            let hardRemove = [] // 物理删除
            let notHardRemove = [] // 非物理删除
            const hardKeys = ['P', 'A1', 'D0']
            list.forEach(item => {
                hardKeys.includes(item.consignmentStatus) ? hardRemove.push(item) : notHardRemove.push(item)
            })
            hardRemove.forEach(item => {
                const i = item.consignmentIndex
                const index = consignmentSaveVos.findIndex(vo => vo.consignmentIndex === i)
                index >= 0 && consignmentSaveVos.splice(index, 1)
            })

            // 非物理删除的数据处理
            if (notHardRemove.length === 0) {
                return false
            }
            let tempArr = notHardRemove.map(item => item.consignmentId).join(',')
            let obj = {
                manifestId: this.manifestId,
                consignmentIds: tempArr.join(),
                functionCode: 3
            }
            this.$refs.changeReasonModalRef.init(obj)
        },
        // 提运单申报
        declareHandle () {
            let list = this.selectedBillsData

            if (list.length === 0) {
                this.$Message.warning('请选择提运单')
                return false
            }

            let isFull = true
            for (let i in this.companyObj) {
                if (!this.companyObj[i]) {
                    isFull = false
                    break
                }
            }

            if (!isFull) { // 如果舱单传输人名称信息不全
                this.$refs.representativeModalRef.init(this.companyObj, this.customsCodeList, 'editPre')
                return false
            }

            let validMainForm = false
            this.$refs.customsManifestRef.validate(v => (validMainForm = v))
            if (!validMainForm) {
                this.$Message.warning('请检查基本信息的数据')
                return
            }
            /**
             * 申报提运单步骤：
             * 1、保存舱单
             * 2、申报提运单
             * 3、如果有error，弹窗，可取消，不可继续申报
             * 4、如果有wain，弹窗，可继续申报
             * */

            let params = this.assemblData()
            unifySaveManifest(params).then(res => { // 保存舱单
                if (res.data.success) { // 申报提运单
                    this.manifestId = res.data.data.success
                    this.queryManifestInfo(this.manifestId).then(response => {
                        if (response.data.success) {
                            let obj = {
                                manifestId: this.manifestId,
                                consignmentIds: this.getSelectConsignmentIds(list),
                                functionCode: 9
                            }
                            this.selectedBillsData = []
                            this.billsDeclareHandle(obj)
                        }
                    })
                } else {
                    this.$Message.error(res.data.msg)
                }
            })
        },
        // 申报提运单方法
        billsDeclareHandle (obj) {
            sendManifestToSingleWindow(obj).then(res => {
                if (res.data.success) {
                    this.$Message.success('申报成功')
                } else {
                    this.$refs.declareFailureRef.init(res.data.data, obj, '申报失败') // 申报失败
                }
            })
        },
        // 提运单操作（保存/修改）
        handlerBillsForm () {
            this.$refs.billsFormRef.validate((valid) => {
                if (valid) {
                    if (this.billsDataCurrentIndex || this.billsDataCurrentIndex === 0) {
                        // 如果是修改提运单
                        this.consignmentSaveVos.splice(this.billsDataCurrentIndex, 1, JSON.parse(JSON.stringify(this.billsForm)))
                        this.consignmentSaveVos.forEach((item, index) => {
                            item.consignmentIndex = index + 1
                        })
                        if (this.billsEdit) {
                            /**
                             * billsEdit：true, 修改提运单，
                             * 执行步骤 1.保存舱单  2.修改数据  3.选择修改原因  4.处理修改错误(error || warn)
                             **/
                            let params = this.assemblData()
                            unifySaveManifest(params).then(res => { // 保存舱单
                                if (res.data.success) {
                                    this.manifestId = res.data.data.success
                                    this.updateHandle(this.billsForm.consignmentId) // 修改数据
                                    this.clearBillsForm()
                                } else {
                                    this.$Message.error(res.data.msg)
                                }
                            })
                        } else {
                            let msg = ['', 'P', 'A1', 'A03', 'A03'].includes(this.billsForm.consignmentStatus) ? '保存成功' : '修改成功'
                            this.$Message.success(msg)
                            this.clearBillsForm()
                        }
                    } else {
                        this.billsForm.consignmentIndex = this.consignmentSaveVos.length + 1
                        this.billsForm.consignmentStatus = 'P'
                        this.billsForm.consignmentCargoVos = []
                        this.billsForm.consignmentContainers = []
                        this.billsForm.consignmentCountryList = []

                        let isRepeat = this.consignmentSaveVos.some(item => item.billNo === this.billsForm.billNo)
                        if (isRepeat) {
                            this.$Message.warning('提（运）单号已存在')
                            return false
                        }
                        this.consignmentSaveVos.push(JSON.parse(JSON.stringify(this.billsForm)))
                        this.clearBillsForm() // 保存后重置表单
                    }
                }
            })
        },
        // 提运单表格单击事件
        billsRowClick (data, index) {
            this.resetBillsForm()

            for (let i in this.billsForm) {
                this.billsForm[i] = data[i]
            }
            // 海关货物通关代码默认公路口岸直通
            this.billsForm.cargoClearanceCode = this.billsForm.cargoClearanceCode || 'RD01'
            // 获得途径国家
            this.billsForm.countryInfo = data.consignmentCountryList
                .map(item => item.countryCode)
                .join(',')
            this.billsDataCurrentIndex = index
            this.parentParams = {
                index: index,
                data: data
            }
        },
        // 获取选中的提运单id
        getSelectConsignmentIds (list) {
            let arr = []
            list.forEach(item => {
                const index = item.consignmentIndex
                const data = this.consignmentSaveVos[index - 1]
                data && arr.push(data.consigneeId)
            })
            return arr.join(',')
        },
        // 货物总件数获得焦点
        totalPackageQuantityGetFocus () {
            $('.totalPackageQuantity').find('.ivu-input').focus()
        }
    }
}
